package com.zxy.ziems.server.alarm.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.zxy.btp.common.response.PageResult;
import com.zxy.ziems.server.alarm.convertor.AlarmConvertor;
import com.zxy.ziems.server.alarm.mapper.AlarmRuleMapper;
import com.zxy.ziems.server.alarm.pojo.dto.AlarmRuleAddDTO;
import com.zxy.ziems.server.alarm.pojo.entity.AlarmRuleEntity;
import com.zxy.ziems.server.alarm.pojo.entity.AlarmRuleRangeEntity;
import com.zxy.ziems.server.alarm.pojo.param.AlarmTypePageParam;
import com.zxy.ziems.server.alarm.pojo.vo.AlarmRuleRangeVO;
import com.zxy.ziems.server.alarm.pojo.vo.AlarmRuleRoleVO;
import com.zxy.ziems.server.alarm.pojo.vo.AlarmRuleVO;
import com.zxy.ziems.server.alarm.service.AlarmRuleRangeService;
import com.zxy.ziems.server.alarm.service.AlarmRuleRoleService;
import com.zxy.ziems.server.alarm.service.AlarmRuleService;
import com.zxy.ziems.server.device.pojo.entity.DeviceTypeEntity;
import com.zxy.ziems.server.device.service.DeviceTypeService;
import com.zxy.ziems.server.domain.User;
import com.zxy.ziems.server.mybatis.core.service.ServiceImplX;
import com.zxy.ziems.server.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Copyright (C),
 * @ClassName: AlarmRuleServiceImpl
 * @Author: yanzhiwei
 * @Description:
 * @Date: 2024/4/9 16:23
 */
@Service
public class AlarmRuleServiceImpl extends ServiceImplX<AlarmRuleMapper, AlarmRuleEntity> implements AlarmRuleService {

    @Autowired
    private DeviceTypeService deviceTypeService;


    @Override
    public void saveAlarmRuleEntity(AlarmRuleAddDTO alarmRuleAddDTO) {
        AlarmRuleEntity alarmRuleEntity = new AlarmRuleEntity();
        BeanUtils.copyProperties(alarmRuleAddDTO, alarmRuleEntity);
        this.saveOrUpdate(alarmRuleEntity);


        List<AlarmRuleRangeEntity> alarmRuleRangeEntityList = alarmRuleAddDTO.getAlarmRangeList().stream().map(m -> {
            AlarmRuleRangeEntity alarmRuleRangeEntity = new AlarmRuleRangeEntity();
            BeanUtils.copyProperties(m, alarmRuleRangeEntity);
            alarmRuleRangeEntity.setDeviceTypeCode(Optional.ofNullable(deviceTypeService.loadById(m.getDeviceTypeId())).map(DeviceTypeEntity::getCode).orElse(""));
            return alarmRuleRangeEntity;
        }).collect(Collectors.toList());

        // 保存，修改告警范围
        alarmRuleRangeService.saveOrUpdateAlarmRuleRange(alarmRuleEntity.getId(), alarmRuleRangeEntityList);


        // 需要保存的roleId
        List<AlarmRuleRoleVO> alarmRuleRoleVOList = alarmRuleAddDTO.getAlarmRuleRoleVOList();
        List<String> roleList = alarmRuleRoleVOList.stream().map(AlarmRuleRoleVO::getRoleId).distinct().collect(Collectors.toList());


        // 保存，修改通知角色
        alarmRuleRoleService.saveOrUpdateAlarmRuleRole(alarmRuleEntity.getId(), roleList);

    }

    @Override
    public void saveAlarmRuleEntity(String id, Integer status) {
        AlarmRuleEntity alarmRuleEntity = new AlarmRuleEntity();
        alarmRuleEntity.setId(id);
        alarmRuleEntity.setStatus(status);
        this.saveOrUpdate(alarmRuleEntity);
    }

    @Override
    public PageResult<AlarmRuleVO> pageListBy(AlarmTypePageParam param) {
        PageResult<AlarmRuleEntity> pageResult = customPage(param, (page, aPageParam) -> baseMapper.queryPageList(page, aPageParam));

        Set<String> ruleIdSet = new HashSet<>();
        Set<String> alarmUpdateUserIdSet = new HashSet<>();
        for (AlarmRuleEntity entity : pageResult.getList()) {
            if (StrUtil.isNotBlank(entity.getId())) {
                ruleIdSet.add(entity.getId());
            }
            if (StrUtil.isNotBlank(entity.getUpdateUserId())) {
                alarmUpdateUserIdSet.add(entity.getUpdateUserId());
            }
        }

        Map<String, List<AlarmRuleRoleVO>> deviceEntityMap = alarmRuleRoleService.listByIdList(ruleIdSet).stream()
                .collect(Collectors.groupingBy(AlarmRuleRoleVO::getRuleId));

        Map<String, List<AlarmRuleRangeVO>> alarmRuleRangMap = alarmRuleRangeService.listByIdList(ruleIdSet).stream()
                .collect(Collectors.groupingBy(AlarmRuleRangeVO::getRuleId));

        Map<String, User> userVoMap = userService.listByIds(alarmUpdateUserIdSet).stream()
                .collect(Collectors.toMap(User::getUserId, (a) -> a));


        List<AlarmRuleVO> list = pageResult.getList()
                .stream()
                .map((entity) -> {
                    List<AlarmRuleRoleVO> alarmRuleRoleVOList = deviceEntityMap.get(entity.getId());
                    List<AlarmRuleRangeVO> alarmRuleRangeVOList = alarmRuleRangMap.get(entity.getId());
                    User user = StrUtil.isBlank(entity.getUpdateUserId()) ? null : userVoMap.get(entity.getUpdateUserId());

                    AlarmRuleVO alarmRuleVO = AlarmConvertor.INSTANCE.alarmRuleDOConvertor2VO(
                            entity,
                            user);
                    alarmRuleVO.setAlarmRuleRoleVOList(alarmRuleRoleVOList);
                    alarmRuleVO.setAlarmRangeList(alarmRuleRangeVOList);
                    return alarmRuleVO;
                }).toList();
        return new PageResult<>(pageResult.getTotal(), list);
    }

    @Override
    public boolean deleteById(String id) {
        // 删除告警范围
        alarmRuleRangeService.deleteAlarmRuleRangeByRuleId(id);

        // 删除通知角色
        alarmRuleRoleService.deleteAlarmRuleRoleByRuleId(id);

        // 删除
        return this.removeById(id);
    }

    @Override
    public AlarmRuleEntity loadById(String id) {
        return baseMapper.selectById(id);
    }

    @Override
    public List<AlarmRuleEntity> listByIds(Set<String> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return baseMapper.selectBatchIds(ids);
    }


    private AlarmRuleRoleService alarmRuleRoleService;

    private AlarmRuleRangeService alarmRuleRangeService;

    private UserService userService;

    @Autowired
    public void setAlarmRuleRoleService(AlarmRuleRoleService alarmRuleRoleService) {
        this.alarmRuleRoleService = alarmRuleRoleService;
    }

    @Autowired
    public void setAlarmRuleRangeService(AlarmRuleRangeService alarmRuleRangeService) {
        this.alarmRuleRangeService = alarmRuleRangeService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

}
